#include "http_file_download.h"
#include <iostream>
using namespace std;
using namespace bestv;


void downloadFunc(void* param) {
	bestv::BtvUInt64 startIndex(0, 0);
	bestv::HttpFileDownload* httpFileDownload = reinterpret_cast<HttpFileDownload*>(param);
	HttpFileDownload::statusT status;
	bestv::BtvUInt64 downloadedBytes;
	btvClockT startTime;
	
	startTime =  btvapiTimeNow();
	
	if(httpFileDownload->start()== BTV_NO_ERROR) {
		printf("Downloading...\n");
		do{
			status = httpFileDownload->downloadDataChunk();	
		}
		while(status == HttpFileDownload::DOWNLOAD_NOT_FINISHED);
	}

	downloadedBytes = httpFileDownload->getNumberOfDownloadedBytes();
	btvClockT stopTime =  btvapiTimeNow();
	btvClockT ellapsedTime = btvapiTimeMinus(startTime, stopTime);
	/*
		Calculation valid only
		for files smaller than 2 GB.
		Good enough for the tests.
	*/
	int bytes = downloadedBytes.getL();

	double bitrate = (8. * bytes * btvapiClocksPerSec()) / ellapsedTime;

	printf("Downloaded bytes %d MB\n", bytes/1000000);
	printf("Average bitrate %d Mbit/s\n", (int)(bitrate/1000000));
}



void main(){
	BandwidthManager::getInstance().setInitialSharedBandwidth(10000000000);
	BandwidthManager::getInstance().setHighBandwidthShare(0.8);
		
	bestv::BtvUInt64 startIndex(0, 0);

	bestv::BtvString URL("http://127.0.0.1/300MB.ts"); 
	bestv::BtvString URL2("http://127.0.0.1/almost2G.ts"); 
	bestv::BtvString URL3("http://127.0.0.1/file4.ts"); 
	//bestv::BtvString bigFileUrl("http://127.0.0.1/fileBig.ts"); 
	bestv::BtvString bigFileUrl("http://127.0.0.1/300MB.ts"); 
	bestv::BtvString almost2GUrl("http://127.0.0.1/almost2G.ts"); 
	bestv::BtvString fileName("d1.ts"); 
	bestv::BtvString fileName2("d2.ts");


	if(0) {
		//*******************************
		//Test to calculate maximum speed
		//*******************************

		BandwidthManager::getInstance().setInitialSharedBandwidth(20000000000);
		
		bestv::HttpFileDownload *httpFileDownload = new HttpFileDownload(bigFileUrl, 
			fileName, 
			BandwidthManager::HIGH_PRIORITY, 
			startIndex);

		downloadFunc(httpFileDownload);
		httpFileDownload->stop();
		delete httpFileDownload;

		printf("End of first test\n");
		printf("Press Return to Continue with the next test.\n");
		getchar();
	}

	if(0) {
		//*********************
		//One download Forever!
		//*********************
		BandwidthManager::getInstance().setInitialSharedBandwidth(100000000);
		while(1){
			bestv::HttpFileDownload *httpFileDownload = new HttpFileDownload(almost2GUrl, 
				fileName2, 
				BandwidthManager::HIGH_PRIORITY, 
				startIndex);

			downloadFunc(httpFileDownload);
			httpFileDownload->stop();
			delete httpFileDownload;
		}
		printf("End of first test\n");
		printf("Press Return to Continue with the next test.\n");
		getchar();
	}

	if(1) {
		//*********************
		//One dynamic download
		//*********************

		BandwidthManager::getInstance().setInitialSharedBandwidth(30000000);
		BandwidthManager::getInstance().setDynamicBwConsumption(true);
		
		bestv::BtvString almost2GUrl("http://10.18.4.113/almost2G.ts");

		bestv::BtvString dynamicDownloadFilename("dynamicDownload.ts");

		while(1){
			bestv::HttpFileDownload *httpFileDownload = new HttpFileDownload(almost2GUrl, 
				dynamicDownloadFilename, 
				BandwidthManager::HIGH_PRIORITY, 
				startIndex);

			downloadFunc(httpFileDownload);
			httpFileDownload->stop();
			delete httpFileDownload;
		}
		printf("End of first test\n");
		printf("Press Return to Continue with the next test.\n");
		getchar();
	}



	if(0){
		/*case 1 : Two downloads with the same Priority */
		printf("*************************************************\n");
		printf("* case 1 : Two downloads with the same Priority *\n");
		printf("*************************************************\n");
		btvTaskT taskHandle1, taskHandle2;

		bestv::HttpFileDownload httpFileDownload(URL, fileName, BandwidthManager::HIGH_PRIORITY, startIndex);
		bestv::HttpFileDownload httpFileDownload1(URL, fileName2, BandwidthManager::HIGH_PRIORITY, startIndex);

		btvapiCreateTask(&taskHandle1, downloadFunc, &httpFileDownload, BTV_PRIORITY_MEDIUM);
		btvapiCreateTask(&taskHandle2, downloadFunc, &httpFileDownload1, BTV_PRIORITY_MEDIUM);

		btvapiJoinTask(taskHandle1);
		btvapiJoinTask(taskHandle2);

		btvapiDeleteTask(taskHandle1);
		btvapiDeleteTask(taskHandle2);

		printf("Press Return Continue with the next test\n");
		getchar();
	}

	
	if(0){

		/*case2 : One download of high priority and two downloads of low priority.*/
		printf("*************************************************\n");
		printf("* case 2 : One high download two low downloads  *\n");
		printf("*************************************************\n");
		btvTaskT taskHandle3, taskHandle4, taskHandle5;

		//bestv::BtvString URL2("http://127.0.0.1:8080/file3.flv"); 
		//bestv::BtvString fileNmae2("file3.flv"); 
		//bestv::BtvString URL3("http://127.0.0.1:8080/file4.flv"); 
		//bestv::BtvString fileNmae3("file4.flv"); 
		//bestv::BtvString fileNmae4("file5.flv"); 

		
		bestv::BtvString fileNmae2("file3.ts"); 
		
		bestv::BtvString fileNmae3("file4.ts"); 
		bestv::BtvString fileNmae4("file5.ts"); 

		bestv::HttpFileDownload httpFileDownload2(URL2, fileNmae2, BandwidthManager::HIGH_PRIORITY, startIndex);
		bestv::HttpFileDownload httpFileDownload3(URL3, fileNmae3, BandwidthManager::LOW_PRIORITY, startIndex);
		bestv::HttpFileDownload httpFileDownload4(URL3, fileNmae4, BandwidthManager::LOW_PRIORITY, startIndex);

		btvapiCreateTask(&taskHandle3, downloadFunc, &httpFileDownload2, BTV_PRIORITY_MEDIUM);
		btvapiCreateTask(&taskHandle4, downloadFunc, &httpFileDownload3, BTV_PRIORITY_MEDIUM);
		btvapiCreateTask(&taskHandle5, downloadFunc, &httpFileDownload4, BTV_PRIORITY_MEDIUM);

		btvapiJoinTask(taskHandle3);
		btvapiJoinTask(taskHandle4);
		btvapiJoinTask(taskHandle5);

		btvapiDeleteTask(taskHandle3);
		btvapiDeleteTask(taskHandle4);
		btvapiDeleteTask(taskHandle5);

		printf("Press Return Continue with the next test\n");
		getchar();
	
	}

	bestv::BtvString fileNmae5("file6.flv"); 
	bestv::BtvString fileNmae6("file7.flv"); 
	bestv::BtvString fileNmae7("file8.flv"); 
	bestv::BtvString fileNmae8("file9.flv"); 

		
	if(0){

		/*case3 : Two downloads of high priority and two downloads of low priority.*/
		printf("*************************************************\n");
		printf("* case 3 : Two high downloads and low downloads *\n");
		printf("*************************************************\n");
		btvTaskT taskHandle6, taskHandle7, taskHandle8, taskHandle9;


		bestv::HttpFileDownload httpFileDownload5(URL2, fileNmae5, BandwidthManager::HIGH_PRIORITY, startIndex);
		bestv::HttpFileDownload httpFileDownload6(URL2, fileNmae6, BandwidthManager::HIGH_PRIORITY, startIndex);
		bestv::HttpFileDownload httpFileDownload7(URL3, fileNmae7, BandwidthManager::LOW_PRIORITY, startIndex);
		bestv::HttpFileDownload httpFileDownload8(URL3, fileNmae8, BandwidthManager::LOW_PRIORITY, startIndex);

		btvapiCreateTask(&taskHandle6, downloadFunc, &httpFileDownload5, BTV_PRIORITY_MEDIUM);
		btvapiCreateTask(&taskHandle7, downloadFunc, &httpFileDownload6, BTV_PRIORITY_MEDIUM);
		btvapiCreateTask(&taskHandle8, downloadFunc, &httpFileDownload7, BTV_PRIORITY_MEDIUM);
		btvapiCreateTask(&taskHandle9, downloadFunc, &httpFileDownload8, BTV_PRIORITY_MEDIUM);

		btvapiJoinTask(taskHandle6);
		btvapiJoinTask(taskHandle7);
		btvapiJoinTask(taskHandle8);
		btvapiJoinTask(taskHandle9);

		btvapiDeleteTask(taskHandle6);
		btvapiDeleteTask(taskHandle7);
		btvapiDeleteTask(taskHandle8);
		btvapiDeleteTask(taskHandle9);

		printf("Press Return Continue with the next test\n");
		getchar();
	}

	if(0){

		/*case (4)Same as (3) but make one of the download to download a much smaller file so when it finishes the bandwidht is re-shared between the remaining downloads.*/
		printf("*************************************************\n");
		printf("* case 4 :										*\n");
		printf("*************************************************\n");
		btvTaskT taskHandle66, taskHandle77, taskHandle88, taskHandle99;
		bestv::BtvString fileNmae55("file10.flv"); 

		bestv::BtvString fileNmae66("file11.flv"); 
		bestv::BtvString fileNmae77("file12.flv"); 
		bestv::BtvString fileNmae88("file13.flv"); 

		bestv::BtvString URL66("http://127.0.0.1:8080/fileShort.flv"); 
		bestv::HttpFileDownload httpFileDownload55(URL66, fileNmae5, BandwidthManager::HIGH_PRIORITY, startIndex);	//short download
		bestv::HttpFileDownload httpFileDownload66(URL2, fileNmae6, BandwidthManager::HIGH_PRIORITY, startIndex);
		bestv::HttpFileDownload httpFileDownload77(URL3, fileNmae7, BandwidthManager::LOW_PRIORITY, startIndex);
		bestv::HttpFileDownload httpFileDownload88(URL3, fileNmae8, BandwidthManager::LOW_PRIORITY, startIndex);

		btvapiCreateTask(&taskHandle66, downloadFunc, &httpFileDownload55, BTV_PRIORITY_MEDIUM);
		btvapiCreateTask(&taskHandle77, downloadFunc, &httpFileDownload66, BTV_PRIORITY_MEDIUM);
		btvapiCreateTask(&taskHandle88, downloadFunc, &httpFileDownload77, BTV_PRIORITY_MEDIUM);
		btvapiCreateTask(&taskHandle99, downloadFunc, &httpFileDownload88, BTV_PRIORITY_MEDIUM);

		btvapiJoinTask(taskHandle66);
		btvapiJoinTask(taskHandle77);
		btvapiJoinTask(taskHandle88);
		btvapiJoinTask(taskHandle99);

		btvapiDeleteTask(taskHandle66);
		btvapiDeleteTask(taskHandle77);
		btvapiDeleteTask(taskHandle88);
		btvapiDeleteTask(taskHandle99);
	}

}